package com.scfinance.SPD.util;


import com.scfinance.SPD.externalReq.SPDBankPAD;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by admin on 2017/7/13.
 */
public class ImageUtil {

    public static final String UPLOADIMAGE_URL = "uploadImage.fileUrl";

    public static final String PROJECT_FILE = "project.getfileurl";

    public static final String PROJECTURL = PropsUtil.getProperty(PROJECT_FILE);

    private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    /**
     * 取出数据库中的文件名转为包含文件名，大图url，小图url的字符串
     *
     * @return 转换好的json字符串
     */
    public static String imgNametoJson(String fileName) {
        if (Validator.isNull(fileName)) {
            return null;
        }
        String mapString = null;
        Map<String, String> map = new HashMap<String, String>();
        String[] sp = fileName.split("\\.");

        if (OSSUtil.isFileExist(fileName)) {  //如果图片存在OSS上
            //图片存在OOS上
            String imagePath = OSSUtil.getImageUrl(fileName);
            if (imagePath != null) {
                map.put("minImg", imagePath);
                map.put("maxImg", imagePath);
            }
        } else {
            map.put("minImg", PROJECTURL + sp[0] + "SA" + "." + sp[1]);    // 缩略图地址
            map.put("maxImg", PROJECTURL + fileName);    // 大图地址
        }
        map.put("name", fileName);    // 图片名称，唯一
        mapString = String.valueOf(JSONObject.fromObject(map));
        return mapString;
    }

    /**
     * 取出数据库中的文件名转为包含文件名，大图url，小图url的字符串
     *
     * @return 转换好的map
     */
    public static Map<String, String> imgNametoMap(String fileName) {
        if (Validator.isNull(fileName)) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();
        if (Validator.isNotNull(fileName)) {
            String[] sp = fileName.split("\\.");
            String imagePath = OSSUtil.getImageUrl(fileName);
            if (imagePath != null) {
                map.put("minImg", imagePath);
                map.put("maxImg", imagePath);
            }
            map.put("name", fileName);    // 图片名称，唯一
        }
        return map;
    }

    public static Map<String, String> imgNameListToDoubleString(String fileNameList) {
        String maxImgs = "";
        String minImgs = "";
        if (Validator.isNotNull(fileNameList)) {   // 如果不为空
            if (fileNameList.indexOf(",") != -1) {    // 说明有多个文件
                String[] fileNames = fileNameList.split(",");
                for (String fn : fileNames) {
                    if (!"null".equals(fn)&&!"".equals(fn)&&fn!=null){
                        Map<String, String> map = ImageUtil.imgNametoMap(fn);
                        maxImgs += map.get("maxImg") + ",";
                        minImgs += map.get("minImg") + ",";
                    }
                }
                // 处理字符串
                maxImgs = maxImgs.substring(0, maxImgs.lastIndexOf(","));
                minImgs = minImgs.substring(0, minImgs.lastIndexOf(","));
            } else {    // 否则就说明是一个文件
                if (!"null".equals(fileNameList)&&!"".equals(fileNameList)&&fileNameList!=null){
                    Map<String, String> map = ImageUtil.imgNametoMap(fileNameList);
                    maxImgs = map.get("maxImg");
                    minImgs = map.get("minImg");
                }
            }
        }
        // 组装Map
        Map<String, String> map = new HashMap<String, String>();
        map.put("names", fileNameList);
        map.put("maxImgs", maxImgs);
        map.put("minImgs", minImgs);
        return map;
    }

    public static File renameImage(String[] imageUrls, String appid, String loanOrderId) {
        File files = null;
        try {
            File sf = new File(PropsUtil.getProperty(UPLOADIMAGE_URL) + loanOrderId);
            File backUpfile = new File(PropsUtil.getProperty(UPLOADIMAGE_URL) + loanOrderId + "backUp");
            for (int i = 0; i < imageUrls.length; i++) {
                String urlString = ImageUtil.imgNameListToDoubleString(imageUrls[i]).get("maxImgs");
                // 忽略空路径
                if (StringUtils.isBlank(urlString)) {
                    System.out.println("图片列表中存在空路径。");
                    continue;
                }
                URL url = new URL(urlString);
                URLConnection con = url.openConnection();
                con.setConnectTimeout(5 * 1000);
                InputStream is = con.getInputStream();

                byte[] bs = new byte[1024];
                int len;
                if (!sf.exists()) {
                    sf.mkdirs();
                }
                if (!backUpfile.exists()){
                    backUpfile.mkdirs();
                }
                String imageType = ".jpg";
                //判断图片是否非JPG
                String outFileName =PropsUtil.getProperty(UPLOADIMAGE_URL) + loanOrderId + "/";
                String originalPicName = appid + "_" + i + urlString.substring(urlString.lastIndexOf("."), urlString.lastIndexOf("?"));
//                String originalPic = outFileName + appid + "_" + i + urlString.substring(urlString.lastIndexOf("."), urlString.lastIndexOf("?"));
                OutputStream os = new FileOutputStream(outFileName + originalPicName);
                OutputStream bkOs = new FileOutputStream(PropsUtil.getProperty(UPLOADIMAGE_URL) +
                        loanOrderId + "backUp/" + i + urlString.substring(urlString.lastIndexOf("."), urlString.lastIndexOf("?")));
                while ((len = is.read(bs)) != -1) {
                    bkOs.write(bs, 0, len);
                    os.write(bs, 0, len);
                }
                bkOs.close();
                os.close();
                is.close();

                String imgFormat = getExtension(new File(outFileName + originalPicName));
                String outPicName = appid + "_" + i + imageType;
//                String jpgPic = outFileName + appid + "_" + i + imageType;
                if (!imgFormat.equals("JPEG")) {
                    forJpg(outFileName + originalPicName, outFileName + outPicName);
                }else {
                    outPicName = originalPicName;
                }
                resizeImageFile(outFileName + outPicName);
                byte[] buffer = File2byte(outFileName + outPicName);
                // 图片混淆
                byte[] confusionBuffer = SPDBankPAD.confusion(buffer);
                byte2File(confusionBuffer, outFileName, outPicName);
            }
            files = new File(PropsUtil.getProperty(UPLOADIMAGE_URL) + loanOrderId);
            logger.info("***BUG图片重名结束***");
        } catch (IOException e) {
            logger.info("***BUG图片重名出错***");
            e.printStackTrace();
        }
        return files;
    }

    public static File renameImageAlone(String pathName, String appId) throws Exception {
        File sf = new File(pathName);
        File[] fileLists = sf.listFiles();
        Integer index = 0;
        File uploadFile = new File(pathName + appId);
        for (File file : fileLists) {
            InputStream is = new FileInputStream(file);
            byte[] bs = new byte[1024];
            int len;
            if (!uploadFile.exists() && !uploadFile.isDirectory()) {
                uploadFile.mkdirs();
            }
            String imageName = file.getName();
            String imageType = imageName.substring(imageName.lastIndexOf("."));
            OutputStream os = new FileOutputStream(uploadFile.getPath() + "/" + appId + "_" + index + imageType);
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            os.close();
            is.close();

            byte[] buffer = File2byte(uploadFile.getPath() + "/" + appId + "_" + index + imageType);
            // 图片混淆
            byte[] confusionBuffer = SPDBankPAD.confusion(buffer);
            byte2File(confusionBuffer, uploadFile.getPath() + "/", appId + "_" + index + imageType);

            index++;
        }
        File files = new File(pathName + appId);
        return files;
    }

    public static File renameImageTest(String appId) throws Exception {
        File sf = new File("d:/uploadImage");
        File[] fileLists = sf.listFiles();
        Integer index = 0;
        File uploadFile = new File("d:/uploadFile" + appId);
        for (File file : fileLists) {
            InputStream is = new FileInputStream(file);
            byte[] bs = new byte[1024];
            int len;
            if (!uploadFile.exists() && !uploadFile.isDirectory()) {
                uploadFile.mkdirs();
            }
            OutputStream os = new FileOutputStream(uploadFile.getPath() + "/" + appId + "_" + index + ".jpg");
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            os.close();
            is.close();

            byte[] buffer = File2byte(uploadFile.getPath() + "/" + appId + "_" + index + ".jpg");
            // 图片混淆
            byte[] confusionBuffer = SPDBankPAD.confusion(buffer);
            byte2File(confusionBuffer, uploadFile.getPath() + "/", appId + "_" + index + ".jpg");

            index++;
        }
        File files = new File("d:/uploadFile" + appId);
        return files;
    }

    public static byte[] File2byte(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    public static void byte2File(byte[] buf, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 压缩图片大小
     */
    public static void resizeImageFile(String filePath) {
        File image = new File(filePath);
        float quality = 0.75f;
        long length = 3072 * 1024;  // 3M
        File newFile = new File("/tmp/" + System.currentTimeMillis() + ".jpg"); // 临时文件
        if (image != null&&image.length() > length) {

            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
            String newImage = null;
            try {
                /** 对服务器上的临时文件进行处理 */
                Image srcFile = ImageIO.read(image);
                int w = srcFile.getWidth(null);
                int h = srcFile.getHeight(null);

                /** 宽,高设定 */
                BufferedImage tag = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                tag.getGraphics().drawImage(srcFile, 0, 0, w, h, null);

                /** 压缩之后临时存放位置 */
                FileOutputStream out = new FileOutputStream(newFile);

                Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");
                ImageWriter writer = iter.next();
                ImageOutputStream ios = ImageIO.createImageOutputStream(out);
                writer.setOutput(ios);
                // 得到指定writer的输出参数设置(ImageWriteParam )
                ImageWriteParam iwp = writer.getDefaultWriteParam();
                iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
                iwp.setCompressionQuality(quality); // 设置压缩质量参数
                iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
                ColorModel colorModel = ColorModel.getRGBdefault();
                // 指定压缩时使用的色彩模式
                iwp.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel,
                        colorModel.createCompatibleSampleModel(16, 16)));
                IIOImage iIamge = new IIOImage(tag, null, null);
                writer.write(null, iIamge, iwp);

                out.close();
                writer.dispose();

                InputStream is = new FileInputStream(newFile);
                OutputStream os = new FileOutputStream(new File(filePath));
                byte[] bs = new byte[1024];
                int len;
                while ((len = is.read(bs)) != -1) {
                    os.write(bs, 0, len);
                }
                os.close();
                is.close();
            } catch (Exception e) {
                System.out.println("图片转化失败。" + image.getName());
                e.printStackTrace();
            }
        }
    }

    /**
     * 将图片格式转换为JPG格式
     * @param input
     * @param output
     * @throws IOException
     */
    public static void forJpg(String input,String output) throws IOException {
        BufferedImage bufferedImage;
        try{
            //read image file
            bufferedImage = ImageIO.read(new File(input));
            // create a blank, RGB, same width and height, and a white background
            BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
                    bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
            //TYPE_INT_RGB:创建一个RBG图像，24位深度，成功将32位图转化成24位
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);
            ImageIO.write(newBufferedImage, "jpg", new File(output));
            if (!input.equals(output)){
                FileUtil.delete(input);
            }
        } catch(Exception e) {
            System.err.println("Error: " + e);
            e.printStackTrace();
        }
    }

    /**
     * 获取图片格式函数
     * @param file
     * @return
     */
    public static String getExtension(File file){
        //图片格式
        String format = "";
        ImageInputStream iis = null;
        try{
            iis = ImageIO.createImageInputStream(file);
            Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
            if(iter.hasNext()){
                format = iter.next().getFormatName();
            }
        }catch(IOException e) {
            e.printStackTrace();
        }finally{
            if(iis!=null){
                try{
                    iis.close();
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return format;
    }
}
